use std::str::FromStr;

use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter, QueryOrder};
use sea_orm::ActiveValue::Set;

use common::ctx::get_db_by_key;
use common::error::MyError;
use common::page::{BasePage, PageResult};
use entity::charac_info;
use entity::prelude::CharacInfo;
use model::charac_info::{CharacInfoPage, CreateCharacInfo, UpdateCharacInfo};

use crate::manager::base::BaseManager;

pub struct CharacInfoManager {}

impl BaseManager<i32, charac_info::Model, CharacInfoPage, CreateCharacInfo, UpdateCharacInfo> for CharacInfoManager {
    async fn list() -> Result<Vec<charac_info::Model>, MyError> {
        todo!()
    }

    async fn page(page: CharacInfoPage) -> Result<PageResult<charac_info::Model>, MyError> {
        let mut find = CharacInfo::find();
        //排序
        if let Some(sorter) = page.get_order() {
            let field = charac_info::Column::from_str(sorter.field.as_str()).or_else(|e| {
                Err(MyError::DBError(format!(
                    "获取排序字段失败：{}",
                    e.to_string()
                )))
            })?;
            find = find.order_by(field, sorter.order());
        }

        if let Some(ref account_name) = page.charac_name {
            find = find.filter(charac_info::Column::CharacName.like(format!("%{}%", account_name)));
        }
        if let Some(uid) = page.charac_no {
            find = find.filter(charac_info::Column::CharacNo.eq(uid));
        }

        //校验并获取分页数据
        let page_data = page.check_page_data();
        //每页大小
        let db_conn = &*get_db_by_key("taiwan_cain")?;
        let paginator = find.paginate(db_conn, page_data.page_size);

        //执行分页查询
        let record = paginator.fetch_page(page_data.page - 1).await?;
        //总条数
        let total = paginator.num_items().await?;
        //返回分页结果
        Ok(PageResult {
            page: page_data.page,
            page_size: page_data.page_size,
            total,
            record,
        })
    }

    async fn info(id: i32) -> Result<Option<charac_info::Model>, MyError> {
        let res = CharacInfo::find_by_id(id).one(&*get_db_by_key("taiwan_cain")?).await?;
        Ok(res)
    }

    async fn add(_form: CreateCharacInfo) -> Result<i32, MyError> {
        todo!()
    }

    async fn update(form: UpdateCharacInfo) -> Result<i32, MyError> {
        let entity = CharacInfo::find_by_id(form.charac_no.unwrap())
            .one(&*get_db_by_key("taiwan_cain")?)
            .await?
            .ok_or(MyError::ServerError(format!(
                "charac_info [{:?}] does not exist",
                form.charac_no
            )))?;
        let mut entity: charac_info::ActiveModel = entity.into();
        if form.charac_name.is_some() {
            entity.charac_name = Set(form.charac_name.unwrap());
        }
        if form.lev.is_some() {
            entity.lev = Set(form.lev.unwrap());
        }
        if form.exp.is_some() {
            entity.exp = Set(form.exp.unwrap());
        }
        if form.hp.is_some() {
            entity.hp = Set(form.hp.unwrap());
        }
        if form.max_hp.is_some() {
            entity.max_hp = Set(form.max_hp.unwrap());
        }
        if form.max_mp.is_some() {
            entity.max_mp = Set(form.max_mp.unwrap());
        }
        if form.phy_attack.is_some() {
            entity.phy_attack = Set(form.phy_attack.unwrap());
        }
        if form.phy_defense.is_some() {
            entity.phy_defense = Set(form.phy_defense.unwrap());
        }
        if form.mag_attack.is_some() {
            entity.mag_attack = Set(form.mag_attack.unwrap());
        }
        if form.mag_defense.is_some() {
            entity.mag_defense = Set(form.mag_defense.unwrap());
        }
        if form.inven_weight.is_some() {
            entity.inven_weight = Set(form.inven_weight.unwrap());
        }
        if form.hp_regen.is_some() {
            entity.hp_regen = Set(form.hp_regen.unwrap());
        }
        if form.mp_regen.is_some() {
            entity.mp_regen = Set(form.mp_regen.unwrap());
        }
        if form.move_speed.is_some() {
            entity.move_speed = Set(form.move_speed.unwrap());
        }
        if form.attack_speed.is_some() {
            entity.attack_speed = Set(form.attack_speed.unwrap());
        }
        if form.cast_speed.is_some() {
            entity.cast_speed = Set(form.cast_speed.unwrap());
        }
        let result = entity.update(&*get_db_by_key("taiwan_cain")?).await?;
        Ok(result.charac_no)
    }

    async fn delete(id: i32) -> Result<bool, MyError> {
        let res = CharacInfo::delete_by_id(id).exec(&*get_db_by_key("taiwan_cain")?).await?;
        Ok(res.rows_affected == 1)
    }
}